from faker import Faker
import random
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from data_mock.utils import FileUtil, MysqlUtils_AI

fake = Faker('zh_CN')

# ========== 基础数据配置 ==========
# 肿瘤相关诊断
CANCER_DIAGNOSES = [
    ("C34.901", "肺恶性肿瘤", "T2N1M0"),
    ("C50.902", "乳腺恶性肿瘤", "T1N0M0"),
    ("C16.901", "胃恶性肿瘤", "T3N2M0"),
    ("C18.901", "结肠恶性肿瘤", "T4N1M1"),
    ("C22.001", "肝细胞癌", "T2N0M0")
]

# 血型
BLOOD_TYPES = ["A", "B", "AB", "O"]
RH_TYPES = ["阳性", "阴性"]

# 科室信息
DEPARTMENTS = [
    ("D01", "肿瘤内科", "W01", "肿瘤内科一病区"),
    ("D02", "肿瘤外科", "W02", "肿瘤外科一病区"),
    ("D03", "放疗科", "W03", "放射治疗病区")
]

# 医院信息
HOSPITALS = [
    ("H1001", "北京协和医院", "P01", "东院"),
    ("H1002", "上海瑞金医院", "P02", "总院"),
    ("H1003", "广州中山医院", "P03", "肿瘤分院")
]

# 出院原因
DISCHARGE_REASONS = [
    "治疗完成出院",
    "病情好转出院",
    "自动出院",
    "转院治疗",
    "病情恶化死亡"
]


# ========== 时间范围配置 ==========
def generate_DAY_RANGE(start_day, end_day):
    start = datetime.strptime(start_day, "%Y-%m-%d")
    end = datetime.strptime(end_day, "%Y-%m-%d")
    days = []
    current = start
    while current <= end:
        days.append(current.strftime("%Y-%m-%d"))
        current += relativedelta(days=1)
    return days


DAY_RANGE = generate_DAY_RANGE("2025-08-01", "2025-08-03")


def generate_records_per_day(day: str):
    date_obj = datetime.strptime(day, '%Y-%m-%d')
    return 15 if date_obj.day % 2 == 0 else 8


# ========== 核心生成函数 ==========
def generate_medical_record_records():
    sql_statements = []
    record_count = 0

    patient_id_counter = 2001
    visit_sn_counter = 2001
    record_sn_counter = 10001

    for day in DAY_RANGE:
        RECORDS_PER_day = generate_records_per_day(day)
        for i in range(1, RECORDS_PER_day + 1):
            record_count += 1
            patient_id = f"PT{patient_id_counter}"
            patient_id_counter += 1

            visit_sn = f"VIS{visit_sn_counter}"
            visit_sn_counter += 1

            record_sn = f"REC{record_sn_counter}"
            record_sn_counter += 1

            # 随机选择医院信息
            hospital_code, hospital_name, branch_code, branch_name = random.choice(HOSPITALS)

            # 基础患者信息
            medical_record_no = f"MR{random.randint(100000, 999999)}"
            inpatient_no = f"IP{random.randint(100000, 999999)}"
            name = fake.name()
            gender = random.choice(["男", "女"])
            birth_date = fake.date_of_birth(minimum_age=30, maximum_age=80).strftime('%Y-%m-%d')
            age = random.randint(30, 80)

            # 诊断信息
            diag_code, diag_name, tnm_staging = random.choice(CANCER_DIAGNOSES)
            t, n, m = tnm_staging.split("N")[0][1:], tnm_staging.split("N")[1].split("M")[0], tnm_staging.split("M")[1]

            # 时间信息
            admit_datetime = fake.date_time_between(
                start_date=datetime.strptime(day, "%Y-%m-%d") - timedelta(days=30),
                end_date=datetime.strptime(day, "%Y-%m-%d")
            ).strftime('%Y-%m-%d %H:%M:%S')

            hospital_days = random.randint(3, 30)
            discharge_datetime = (datetime.strptime(admit_datetime, '%Y-%m-%d %H:%M:%S') +
                                  timedelta(days=hospital_days)).strftime('%Y-%m-%d %H:%M:%S')

            record_datetime = discharge_datetime
            yy_collection_datetime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            yy_etl_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

            # 科室信息
            dept_code, dept_name, ward_code, ward_name = random.choice(DEPARTMENTS)

            # 医生信息
            attending_physician = fake.name()
            attending_physician_id = f"DOC{random.randint(100, 999)}"
            chief_physician = fake.name()
            chief_physician_id = f"DOC{random.randint(100, 999)}"
            resident = fake.name()
            resident_id = f"DOC{random.randint(100, 999)}"
            responsible_nurse = fake.name()
            responsible_nurse_id = f"NUR{random.randint(100, 999)}"

            # 费用信息
            total_cost = round(random.uniform(5000, 50000), 2)
            western_medicine_fee = round(total_cost * random.uniform(0.3, 0.6), 2)
            surgical_treatment_fee = round(total_cost * random.uniform(0.1, 0.3), 2) if random.random() > 0.3 else 0

            # 生成yy_record_md5 (模拟MD5)
            yy_record_md5 = f"md5_{random.getrandbits(128):032x}"
            yy_batch_time = day
            yy_record_batch_id = f"BATCH{day}_{i}"

            # 新增联系人信息
            contact_name = fake.name()
            contact_relationship = random.choice(["配偶", "子女", "父母", "兄弟姐妹", "其他亲属"])
            contact_telephone = fake.phone_number()
            contact_address = fake.address()
            home_telephone = fake.phone_number()  # 新增家庭电话

            data = {
                'abo': random.choice(BLOOD_TYPES),
                'admission_condition': random.choice(["危", "急", "一般"]),
                'admission_diagnosis_code': diag_code,
                'admission_diagnosis_name': diag_name,
                'admisson_path': random.choice(["门诊", "急诊", "转院"]),
                'admit_datetime': admit_datetime,
                'admit_department_speciality': dept_name,
                'admit_ward': ward_name,
                'attending_physician': attending_physician,
                'attending_physician_id': attending_physician_id,
                'birth_date': birth_date,
                'chief_physician': chief_physician,
                'chief_physician_id': chief_physician_id,
                'discharge_datetime': discharge_datetime,
                'discharge_department_speciality': dept_name,
                'discharge_reason': random.choice(DISCHARGE_REASONS),
                'discharge_type': random.choice(["医嘱离院", "医嘱转院", "非医嘱离院"]),
                'discharge_ward': ward_name,
                'ethnic_group': random.choice(["汉族", "回族", "满族", "蒙古族"]),
                'from_table': 'MEDICAL_RECORD',
                'from_yy_record_id': f"SOURCE_{random.randint(10000, 99999)}",
                'hospital_code': hospital_code,
                'hospital_days': str(hospital_days),
                'hospital_name': hospital_name,
                'id_card_category': "身份证",
                'id_number': fake.ssn(),
                'is_allergy': random.choice(["有", "无"]),
                'marital_status': random.choice(["已婚", "未婚", "离异"]),
                'medical_payments': random.choice(["医保", "自费", "公费"]),
                'medical_record_no': medical_record_no,
                'medical_record_status': "已归档",
                'nationality': "中国",
                'occupation': random.choice(["工人", "农民", "公务员", "医务人员"]),
                'patient_gender': gender,
                'patient_id': patient_id,
                'patient_name': name,
                'record_datetime': record_datetime,
                'record_sn': record_sn,
                'record_source': "HIS系统",
                'record_status': 1,
                'record_type': "住院病案",
                'rehospitalization_after_discharge_31': random.choice(["有", "无"]),
                'resident': resident,
                'resident_id': resident_id,
                'responsible_nurse': responsible_nurse,
                'responsible_nurse_id': responsible_nurse_id,
                'rh': random.choice(RH_TYPES),
                'total_cost': str(total_cost),
                'treatment_type': random.choice(["手术治疗", "化疗", "放疗", "综合治疗"]),
                'visit_age': str(age),
                'visit_sn': visit_sn,
                'western_medicine_fee': str(western_medicine_fee),
                'surgical_treatment_fee': str(surgical_treatment_fee),
                'tnm_staging': tnm_staging,
                'tnm_t_staging': t,
                'tnm_n_staging': n,
                'tnm_m_staging': m,
                'home_telephone': home_telephone,  # 确保NOT NULL字段有值
                # 新增联系人相关字段
                'contact_name': contact_name,
                'contact_relationship': contact_relationship,
                'contact_telephone': contact_telephone,
                'contact_address': contact_address,
                'yy_collection_datetime': yy_collection_datetime,
                'yy_record_md5': yy_record_md5,
                'yy_upload_status': 0,
                'yy_etl_time': yy_etl_time,
                'yy_upload_time': None,
                'yy_batch_time': yy_batch_time,
                'yy_record_batch_id': yy_record_batch_id,
                'yy_backfill_time': None,
                'yy_backfill_status': None,
                'branch_code': branch_code,
                'branch_name': branch_name,
                'date_for_partition': discharge_datetime
            }

            sql = _generate_sql('b04_1', data)
            sql_statements.append(sql)

    return sql_statements


def _generate_sql(table, data):
    columns = ', '.join([f'`{k}`' for k in data.keys()])
    values = []
    for v in data.values():
        if v is None:
            values.append('NULL')
        elif isinstance(v, (int, float)):
            values.append(str(v))
        else:
            escaped_value = str(v).replace("'", "''")
            values.append(f"'{escaped_value}'")
    return f"INSERT INTO `{table}` ({columns}) VALUES ({', '.join(values)});"


# ========== 执行生成 ==========
if __name__ == "__main__":
    records = generate_medical_record_records()
    # 写入数据库
    MysqlUtils_AI.insert_data_to_hub(records, 'b04_1')
    # 或写入 SQL 文件
    # FileUtil.generate_sql_file(records, "b04_1_medical_records.sql")